{"componentChunkName":"component---src-templates-post-tsx","path":"/React-study_4/","result":{"data":{"markdownRemark":{"html":"<p>State\nstate는 리액트에서 화면을 그려내는 데 굉장히 중요한 역할을 합니다.</p>\n<p>State라는 단어는 한국어로 '상태'라는 뜻이 있는데요. 리액트에서의 state도 그 의미가 다르지 않습니다.</p>\n<p>상태가 바뀔 때마다 화면을 새롭게 그려내는 방식으로 동작을 하는 것이죠.</p>\n<p>리액트에서 state를 만들고, state를 바꾸기 위해서는 일단 useState라는 함수를 활용해야 합니다.</p>\n<p>import { useState } from 'react';</p>\n<p>// ...</p>\n<p>const [num, setNum] = useState(1);</p>\n<p>// ...\n보통 이렇게 Destructuring 문법으로 작성하는데요. useState 함수가 초깃값을 아규먼트로 받고 그에 따른 실행 결과로 요소 2개를 가진 배열의 형태로 리턴을 하기 때문입니다.</p>\n<p>이때 첫 번째 요소가 바로 state이고, 두 번째 요소가 이 state를 바꾸는 setter 함수인데요.</p>\n<p>참고로 위 코드에서도 볼 수 있듯 첫 번째 변수는 원하는 state의 이름(num)을 지어주고, 두 번째 변수에는 state 이름 앞에 set을 붙인 다음 카멜 케이스로 이름을 지어주는 것(setNum)이 일반적입니다.</p>\n<p>state는 변수에 새로운 값을 할당하는 방식으로 변경하는 것이 아니라 이 setter 함수를 활용해야 하는데요. setter 함수는 호출할 때 전달하는 아규먼트 값으로 state 값을 변경해 줍니다.</p>\n<p>그래서 아래 코드처럼 setter 함수를 활용해서 이벤트 핸들러를 등록해두면, 이벤트가 발생할 때마다 상태가 변하면서 화면이 새로 그려지는 것이죠!</p>\n<p>import { useState } from 'react';\nimport Button from './Button';\nimport Dice from './Dice';</p>\n<p>function App() {\nconst [num, setNum] = useState(1);</p>\n<p>const handleRollClick = () => {\nsetNum(3); // num state를 3으로 변경!\n};</p>\n<p>const handleClearClick = () => {\nsetNum(1); // num state를 1로 변경!\n};</p>\n<p>return (</p>\n<div>\n<Button onClick={handleRollClick}>던지기</Button>\n<Button onClick={handleClearClick}>처음부터</Button>\n<Dice color=\"red\" num={num} />\n</div>\n);\n}\n<p>export default App;\n참조형 State\n자바스크립트의 자료형은 크게 기본형(Primitive type)과 참조형(Reference type)로 나눌 수 있다는 사실, 모두 알고 계시죠?</p>\n<p>특히 참조형 값들은 조금 독특한 특성을 가지고 있어서 변수로 다룰 때도 조금 주의해야 할 부분들이 있었는데요. state를 활용할 때도 마찬가지입니다!</p>\n<p>// ...</p>\n<p>const [gameHistory, setGameHistory] = useState([]);</p>\n<p>const handleRollClick = () => {\nconst nextNum = random(6);\ngameHistory.push(nextNum);\nsetGameHistory(gameHistory); // state가 제대로 변경되지 않는다!\n};</p>\n<p>// ...\n위 코드에서 볼 수 있듯 배열 값을 가진 gameHistory에 push 메소드를 이용해서 배열의 값을 변경한 다음, 변경된 배열을 setter 함수로 state를 변경하려고 하면 코드가 제대로 동작하지 않습니다.</p>\n<p>gameHistory state는 배열 값 자체를 가지고 있는 게 아니라 그 배열의 주솟값을 참조하고 있는 건데요. 때문에 push 메소드로 배열 안에 요소를 변경했다고 하더라도 결과적으로 참조하는 배열의 주솟값은 변경된 것이 아니게 됩니다.</p>\n<p>결과적으로 리액트 입장에서는 gameHistory state가 참조하는 주솟값은 여전히 똑같기 때문에 상태(state)가 바뀌었다고 판단하지 않는 것이죠!</p>\n<p>그래서 참조형 state를 활용할 때는 반드시 새로운 참조형 값을 만들어 state를 변경해야 합니다.</p>\n<p>가장 간단한 방법은 Spread 문법(...) 을 활용하는 것이겠죠?</p>\n<p>// ...</p>\n<p>const [gameHistory, setGameHistory] = useState([]);</p>\n<p>const handleRollClick = () => {\nconst nextNum = random(6);\nsetGameHistory([...gameHistory, nextNum]); // state가 제대로 변경된다!\n};</p>\n<p>// ...\n이 참조형 state의 특성을 이해하지 못하면, 간혹 state가 제대로 변경되지 않는 버그가 발생했을 때 원인을 제대로 찾지 못하는 경우가 발생할 수도 있는데요.</p>\n<p>참조형 state를 활용할 땐 반드시 새로운 참조형 값을 만들어서 state를 변경해야 한다는 점.</p>","excerpt":"State\nstate는 리액트에서 화면을 그려내는 데 굉장히 중요한 역할을 합니다. State라는 단어는 한국어로 '상태'라는 뜻이 있는데요. 리액트에서의 state도 그 의미가 다르지 않습니다. 상태가 바뀔 때마다 화면을 새롭게 그려내는 방식으로 …","tableOfContents":"","fields":{"slug":"/React-study_4/"},"frontmatter":{"title":"React state 정리하기","date":"Aug 23, 2021","tags":["react"],"keywords":["Dev.seungwon Jang","seungwon Jang"],"update":"Aug 23, 2021"}}},"pageContext":{"slug":"/React-study_4/","series":[{"slug":"/React-study_1/","title":"React JSX 문법","num":1},{"slug":"/React-study_2/","title":"React commponent 문법","num":2},{"slug":"/React-study_3/","title":"React Props 문법","num":3},{"slug":"/React-study_4/","title":"React state 정리하기","num":4},{"slug":"/React-study_5/","title":"React 디자인 적용하는 방법과 팁","num":5},{"slug":"/React-study_6/","title":"React 배포하기","num":6}],"lastmod":"2021-08-23"}},"staticQueryHashes":["2027115977","694178885"]}